package com.michaelbulava.TFS.vcs.internal;

import com.intellij.openapi.vcs.FilePath;
import com.microsoft.tfs.util.Check;

import java.io.File;

/**
 * Created by mbulava on 5/7/2015.
 */
public abstract class StatusVisitor {

    private void errorCheck(FilePath filePath, ServerStatus serverStatus){
        if (filePath == null)
            throw new IllegalArgumentException("filePath is null");
        if (serverStatus == null)
            throw new IllegalArgumentException("serverStatus is null");
    }

    public final void notVersioned(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performNotVersion(filePath, existsLocally, serverStatus);
    }

    protected abstract void performNotVersion(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void deleted(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performDeleted(filePath, existsLocally, serverStatus);
    }

    protected abstract void performDeleted(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void scheduledForAddition(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performScheduledForAddition(filePath, existsLocally, serverStatus);
    }

    protected abstract void performScheduledForAddition(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void scheduledForDeletion(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performScheduledForDeletion(filePath, existsLocally, serverStatus);
    }

    protected abstract void performScheduledForDeletion(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void checkedOutForEdit(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performCheckedOutForEdit(filePath, existsLocally, serverStatus);
    }

    protected abstract void performCheckedOutForEdit(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void outOfDate(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performOutOfDate(filePath, existsLocally, serverStatus);
    }

    protected abstract void performOutOfDate(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void upToDate(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performUpToDate(filePath, existsLocally, serverStatus);
    }

    protected abstract void performUpToDate(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);
        
    public final void renamed(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performRenamed(filePath, existsLocally, serverStatus);
    }

    protected abstract void performRenamed(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void renamedCheckedOut(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performRenamedCheckedOut(filePath, existsLocally, serverStatus);
    }
    
    protected abstract void performRenamedCheckedOut(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void undeleted(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performUndeleted(filePath, existsLocally, serverStatus);
    }

    protected abstract void performUndeleted(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public final void ignored(FilePath filePath, boolean existsLocally, ServerStatus serverStatus){
        errorCheck(filePath, serverStatus);
        performIgnored(filePath, existsLocally, serverStatus);
    }

    protected abstract void performIgnored(FilePath filePath, boolean existsLocally, ServerStatus serverStatus);

    public void WorkingFolder(FilePath folder){
        Check.notNull(folder, "folder");
        Check.isTrue( folder.isDirectory(), "folder parameter must be a directory");
    }

    public void Unknown(FilePath filePath){

    }
}
